/********************************************************************
(c) 2003-2005 C2217 Studio
Module:    Singleton.h
Author:     Yangjun D.
Created:    9/3/2005   23:17
Purpose:    Implement singleton pattern
History:
*********************************************************************/

#pragma once

#include <memory>
#include <windows.h>
#include <queue>
#include <boost/thread.hpp>
using namespace std;

class CResGuard {
public:
	CResGuard()  { m_lGrdCnt = 0; InitializeCriticalSection(&m_cs); }
	~CResGuard() { DeleteCriticalSection(&m_cs); }
	// IsGuarded is used for debugging
	bool IsGuarded() const { return(m_lGrdCnt > 0); }
public:
	class CGuard {
	public:
		CGuard(CResGuard& rg) : m_rg(rg) { m_rg.Guard(); };
		~CGuard() { m_rg.Unguard(); }
	private:
		CResGuard& m_rg;
	};

private:
	void Guard()   { EnterCriticalSection(&m_cs); m_lGrdCnt++; }
	void Unguard() { m_lGrdCnt--; LeaveCriticalSection(&m_cs); }
	// Guard/Unguard can only be accessed by the nested CGuard class.
	friend class CResGuard::CGuard;
private:
	CRITICAL_SECTION m_cs;
	long m_lGrdCnt;   // # of EnterCriticalSection calls
};



template <class T>
class Singleton
{
public:
	static inline T* instance();
private:
	Singleton(void){}
	~Singleton(void){}
	Singleton(const Singleton&){}
	Singleton & operator= (const Singleton &){}
	static auto_ptr<T> _instance;
	static CResGuard _rs;
};

template <class T>
auto_ptr<T> Singleton<T>::_instance;
template <class T>
CResGuard Singleton<T>::_rs;
template <class T>
inline T* Singleton<T>::instance()
{
	if( 0 == _instance.get() )
	{
		CResGuard::CGuard gd(_rs);
		if( 0== _instance.get())
		{
			_instance.reset ( new T);
		}
	}
	return _instance.get();
}

#define DECLARE_SINGLETON_CLASS( type ) 		friend class auto_ptr< type >;		friend class Singleton< type >;

class queue_UrlPath
{
public:
	void Run()
	{
	}

	void push(UrlPath* _up)
	{
	    boost::mutex::scoped_lock lock(mutex_);
		m_qUrlPath.push(_up);
	}
	void pop()
	{
	    boost::mutex::scoped_lock lock(mutex_);
		m_qUrlPath.pop();
	}
	
	UrlPath * front()
	{	boost::mutex::scoped_lock lock(mutex_);
		return m_qUrlPath.front();
	}
	
	bool isEmpty()
	{
	    return m_qUrlPath.empty();
	}
	
	void size()
	{
	    cout<<"---------------------m_qUrlPath size"<< m_qUrlPath.size()<<endl;
	}

private:
	queue_UrlPath(void)
	{
	}
	virtual ~queue_UrlPath(void)
	{
	}

private:
	queue<UrlPath*> m_qUrlPath;
	DECLARE_SINGLETON_CLASS(queue_UrlPath);
	 boost::mutex mutex_;
};

typedef Singleton<queue_UrlPath> dhw_UrlPath;





